package com.mg;



import org.junit.jupiter.api.Test;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;

public class Main {


    /**
     * 测试读写的弱一致性和最终一致性
     * @throws InterruptedException
     */
    @Test
    public void testConstantProblem() throws InterruptedException {
        // 先初始化一个集合，用来进行测试
        List<Integer> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }

        CountDownLatch cdl = new CountDownLatch(1);
        // 使下面的子线程休眠几秒, 确保该主线程的代码先执行, 目的是为了在集合元素被子线程修改前，获取到集合的iterator
        Iterator<Integer> iterator = list.iterator();

        new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }
            for (int i = 0; i < 10; i++) {
                list.set(i, i * 10);
            }
            cdl.countDown();
        }).start();

        cdl.await();
        // 等到集合被修改完毕之后, 再使用修改前获取到的迭代器iterator进行遍历操作
        while (iterator.hasNext()) {
            System.out.println("遍历：" + System.currentTimeMillis() + " - " + iterator.next());
        }

        Iterator<Integer> iterator2 = list.iterator();
        while (iterator2.hasNext()) {
            System.out.println("遍历2：" + System.currentTimeMillis() + " - " + iterator2.next());
        }
    }

    /**
     * 原始的ArrayList存在多线程同时对一个集合进行修改, 所得到的结果不符合预期的情况
     *
     * @throws InterruptedException
     */
    @Test
    public void testManyThreadProblem() throws InterruptedException {
        List<Integer> list = new MyCopyOnWriteArrayList<>();

        new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                list.add(i);
            }

        }).start();


        new Thread(() -> {
            for (int i = 1000; i < 2000; i++) {
                list.add(i);
            }
        }).start();

        Thread.sleep(1000);

        list.forEach(System.out::println);
        System.out.println(list.get(10));
    }

    @Test
    public void testAdd() {
        List<Integer> list = new MyCopyOnWriteArrayList<>();

        for (int i = 0; i < 10; i++) {
            list.add(i);
        }

        list.add(10, 100);

        list.forEach(System.out::println);
    }

    /**
     * 测试多线程下addIfAbsent的重复添加问题
     *
     * @throws InterruptedException
     */
    @Test
    public void testAddIfAbsent() throws InterruptedException {
        MyCopyOnWriteArrayList<Integer> list = new MyCopyOnWriteArrayList<>();

        CountDownLatch cdl = new CountDownLatch(3);

        new Thread(() -> {
            for (int j = 0; j < 10; j++) {
                list.addIfAbsent(j);
            }
            cdl.countDown();
        }).start();


        new Thread(() -> {
            for (int j = 5; j < 15; j++) {
                list.addIfAbsent(j);
            }
            cdl.countDown();
        }).start();


        new Thread(() -> {
            for (int j = 10; j < 20; j++) {
                list.addIfAbsent(j);
            }
            cdl.countDown();
        }).start();


        cdl.await();
        System.out.println("size = " + list.size());
        list.forEach(System.out::println);
    }

    @Test
    public void testRemoveByIndex() {
        List<Integer> list = new CopyOnWriteArrayList<>();

        for (int i = 0; i < 10; i++) {
            list.add(i);
        }


        list.remove(9);
        list.remove(8);
        list.remove(7);
        list.remove(6);
        list.remove(5);


        System.out.println("size = " + list.size());
        list.forEach(System.out::println);
    }

    public static void main(String[] args) {
        int i = 1;
        i = (++i) + (++i) + (++i);
        System.out.println(i);
    }
//
//    public static void main(String[] args) {
//        int i = 1;
//        int a = ++i;
//        int b = ++i;
//        int c = ++i;
//        i = (++i) + (++i) + (++i);
//        System.out.println(i);
//    }
}